#!/usr/bin/python
# -*- coding: utf-8 -*-
#Programmed by Kaan Akşit

import smtplib, mimetypes, sys, time, pygame, pygame.camera, os, threading, pygame.time, math,numpy, gettext, getopt, getpass, locale
from pygame.locals import *
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage
from threading import Thread

class eposta:
    def __init__(self,me,you,login,password,msg,caption,attachments=None):
      self.msg                 = MIMEMultipart(_subtype='related')
      self.text                = MIMEText(msg)
      self.msg.attach(self.text)
      self.login               = login
      self.msg['Subject']      = caption
      self.msg['From']         = me
      self.msg['To']           = you
      self.password            = password
      if attachments != None:
        for i in attachments:
          fp = open(i, 'rb')
          img = MIMEImage(fp.read(),'png')
          fp.close()
        self.msg.attach(img)
      return
    def send(self):
      self.s = smtplib.SMTP('smtp.gmail.com', 587)
      self.s.ehlo()
      self.s.starttls()
      self.s.ehlo()
      self.s.login(self.login, self.password)
      self.s.sendmail(self.msg['From'],self.msg['To'], self.msg.as_string())
      self.s.quit()
      return True

class window:
    def __init__(self):
        localtime = time.asctime(time.localtime(time.time()))
        print "\x1b\x5b1;33;32m" + localtime + ', Kaan AKŞİT, 2011' + "\x1b[0m"
        print "\x1b\x5b1;31;40m" + _('Pygame version:')+' '+ "\x1b[0m" + str(pygame.version.ver)
        pygame.init()
        window.screen     = pygame.display.set_mode((320, 240),pygame.HWSURFACE)
        print "\x1b\x5b1;31;40m" + _('Video info:')+' '+ "\x1b[0m",
        print "\x1b\x5b1;33;20m", pygame.display.Info()
        self.background = pygame.Surface(window.screen.get_size())
        self.background.set_colorkey((250, 250, 250))
        pygame.display.set_caption(('Takatuka'))
        pygame.display.set_icon(pygame.image.load(filepath("icon.png")))
    def text_blit(self,script,color,posx,posy,font_type,font_size):
        font            = pygame.font.Font(filepath(font_type),font_size)
        text            = font.render(unicode(script), 0, color)
        textpos         = text.get_rect()
        textpos.centerx = posx
        textpos.centery = posy
        self.background.blit(text,textpos)
        return textpos, script
    def refresh(self):
        window.screen.blit(self.background, (0, 0))
        pygame.display.flip()
        return True
    def blit(self,image,rect):
        self.background.fill((100, 100, 100))
        self.background.blit(image,rect)
        return True
        
class camera:
    def __init__(self):
        pygame.camera.init()
        print pygame.camera.list_cameras()
        self.height = 240
        self.width  = 320
        self.area   = self.height*self.width
        self.camera = pygame.camera.Camera(pygame.camera.list_cameras()[0],(self.width,self.height),'RGB')
        self.camera.start()
        self.camera.set_controls(True,True,100)
        print "\x1b\x5b1;31;40m" + _('Camera control:')+' '+ "\x1b[0m" + str(self.camera.get_controls())
        self.image          = self.camera.get_image()
        self.image_rgb      = self.image.copy()
        self.count          = 0
        self.count_limit    = 10
        self.softstart      = 0
        self.surfaces       = []
        self.average        = range(0,self.count_limit)
        self.tolerance      = 0x444433*numpy.ones((self.width,self.height))
        for i in range(0,self.count_limit):
            self.capture()
            self.surfaces.append(self.image)
        return
    def mean(self,obj):
        value = sum(obj)/len(obj)
        return value
    def capture(self):
        self.previous_image = self.image
        if self.camera.query_image():
          self.image          = self.camera.get_image()
        self.rect           = self.image.get_rect()
        return self.image,self.rect
    def comparray(self,a,b):
        c = abs(a.__sub__(b))
        c = c.__ge__(self.tolerance)
        z = numpy.transpose(numpy.dot(c,numpy.ones((self.height,1))))
        self.mask = int(numpy.dot(z,numpy.ones((self.width,1))))
        surface = pygame.surfarray.make_surface(c*255)
        return surface
    def compare(self,limit,fps): 
        global tmem
        if self.count == self.count_limit:
            self.count = 0    
        self.surfaces[self.count] = self.image
        pygame.transform.average_surfaces(self.surfaces,self.image_rgb,True)
        colorarray      = pygame.surfarray.array2d(self.image_rgb)  
        color1ray       = pygame.surfarray.array2d (self.image)
        self.image_comp = self.comparray(color1ray,colorarray)
        percentage      = float(self.mask)/self.area*100
        self.average[self.count] = abs(self.mask)
        if self.mean(self.average) ==0:
           self.average= numpy.ones(self.count_limit)
        if percentage > limit:
          if self.softstart > 10*float(fps):
            self.filename = os.path.expanduser('~')+'/takatuka.png'
            pygame.image.save(self.image, self.filename)
            MyThread().start()
            tmem = time.time()
          else:
            self.softstart +=1
        self.count += 1
        return True
    def reset(self):
        self.camera.stop()
        self.camera.start()
        return True
        
class MyThread(Thread):
   def run(self):
      global tmem, login, password, to
      try:
        if time.time()-tmem > 0.15:
          newmail = eposta(login,to,login,password,'Takatuka!','Takatuka',[cam.filename])
          newmail.send()
          localtime = time.asctime(time.localtime(time.time()))
          print  '\x1b\x5b1;33;32m'+localtime+' '+_('Job done!')+'\x1b[0m'
      except:
        localtime = time.asctime(time.localtime(time.time()))
        print '\x1b\x5b1;31;40m'+localtime+' '+_('Unable to complete!')+'\x1b[0m'
        print sys.exc_info()[0]
      return

def set_values(language):
    global _
    t = gettext.translation('messages',filepath('locale/'),languages=[language])
    _ = t.ugettext
    t.install()
    return

def filepath(filename):
    data_py  = os.path.abspath(os.path.dirname(__file__))
    if data_py == '/usr/bin':
      data_py = '/usr/share/takatuka'
    data_dir = os.path.normpath(os.path.join(data_py, 'data'))
    return os.path.join(data_dir, filename)

def init():
    global global_lang, login, password, to, fps
    global_lang  = locale.getdefaultlocale()[0]
    if os.path.exists(filepath('locale/'+global_lang)) == False:
      global_lang = 'en_US'
    set_values(global_lang)
    try:
        opts, args = getopt.getopt(sys.argv[1:], 'h', ['help'])
    except getopt.error, msg:
        print _('for help use --help or -h')
        sys.exit()
    for o, a in opts:
        if o in ("-h", "--help"):
            print _('Usage: takatuka [youremailaddress@gmail.com] [recevier@somemail.com]\n\nNote that only gmail is supported in the place of [youremailaddress@gmail.com]\n\nSample: takatuka user@gmail.com receiver@somemail.com;example@othermail.com')
            sys.exit()
    try:
        if len(sys.argv) != 3:
           sys.exit()
        else:
           password  = getpass.getpass(_('Enter the password of the mail account and then press enter:'),)
           print _('Sending the sample mail...'),
           login = sys.argv[1]
           to    = sys.argv[2]
           try: 
               newmail = eposta(login,to,login,password,'Takatuka!','Takatuka')
               newmail.send()
           except:
               print _('[FAILED]')
               sys.exit()
    except:
        print _('for help use --help or -h')
        sys.exit()
    print _('[OK]')
    fps          = 5
    return

def main():
    global cam,tmem,fps
    #os.environ['PYGAME_CAMERA'] = 'opencv'
    init()
    screen = window()
    cam    = camera()
    tmem   = time.time()
    clock  = pygame.time.Clock()
    while True:
      events = pygame.event.get()
      for e in events:
          if e.type == QUIT or (e.type == KEYDOWN and e.key == K_ESCAPE):
              sys.exit()
              return
          if e.type == MOUSEBUTTONDOWN:
              pygame.display.toggle_fullscreen()
      cam.capture()
      cam.compare(0.1,int(fps))
      clock.tick(float(fps))
      screen.blit(cam.image_comp,cam.rect)
      screen.text_blit((_('FPS:')+' '+ str(int(clock.get_fps()))),[255,0,0],30,230,'font/ka1.ttf',12)
      screen.refresh()
    return
  
if __name__ == "__main__":
  sys.exit(main())